#ifndef _OGSOLVERBBPV4OPENMP_H_
#define _OGSOLVERBBPV4OPENMP_H_

using namespace std ;

#include <stack>

#include "ogsolverBBPv3.h"

#include "gsupplyLinkProblem.h"
#include "gsupplyLinkSolution.h"
#include "ogsupplyLinkSolutionPartial.h"

// Uncomment this line to parallelize the BBP with OpenMP
#define SOLVER_OPENMP

/**
 * A BBP solver : starts with jobs with last due dates
 *
 * Dans cette version 3 de la BBP, on demarre avec les jobs reordonnes dans le sens des dates dues croissantes. Mais
 * contrairement a l'exploration brutale de la version 2, cette fois on ne considere pas n'importe quel numero de batch.
 * Pour chaque job, on choisit de le rajouter soit dans un batch deja existant dont la capacite residuel est suffisante
 * pour stocker le nouveau job, soit dans un nouveau batch.
 *
 * Le nouveau batch est ordonnance avant les autres batchs deja crees.
 *
 * ATTENTION : Pour que cette solution soit optimale, sachant que l'on
 * part d'un probleme pour lequel les jobs sont classes par date due croissante, il est egalement necessaire que le cout de stockage
 * de tous les jobs soient identiques. Dans le cas contraire, la solution ainsi construite n'est plus certaine d'etre optimale.
 *
 * SPECIFIC FOR UNBALANCED TREE SEARCH (UTS) with OPENMP
 *
 */
class searchnode{
    private:
        int nbrbatch ; // number of batches
        int job ;      // job to place
        vector<double> tabBatchRemainingCapacity ;
        OGSupplyLinkSolutionPartial sol ;

        //int threadid ;

    friend class OGSolverBBPv4openMPiterative ;
    friend ostream& operator<<(ostream&,const searchnode&) ;

} ;

ostream& operator<<(ostream&,const searchnode&) ;

class OGSolverBBPv4openMPiterative :public OGSolverBBPv3 {
    private:
        stack<searchnode> mystack ;

    public:
        OGSolverBBPv4openMPiterative(GSupplyLinkProblem& pb) ;
        ~OGSolverBBPv4openMPiterative() ;

        void solveMain() ;

        void informationOpenMP() ;
        searchnode generateChildNode(const searchnode& , int ) ;
        void depthFirstSearchMultiIterative() ;
} ;






class OGSolverBBPv4openMPrecursive :public OGSolverBBPv3 {

    public:
        OGSolverBBPv4openMPrecursive(GSupplyLinkProblem& pb) ;
        ~OGSolverBBPv4openMPrecursive() ;

        void solveMain() ;

        void informationOpenMP() ;
        void depthFirstSearchMultiRecursive(int, int, OGSupplyLinkSolutionPartial&, vector<double>&) ;
} ;



#endif
